package raytracer;

public class PhongIllumination
{
	final static int difuseIndex = 3;
	final static int ambientIndex = 0;
	final static int specularIndex = 6;
	
	private static float[] Ia = { 0.25f, 0.25f, 0.25f }; // ambient light color
    private static float[] Ids = { 1.0f, 1.0f, 1.0f }; // diffuse and specular light color
    
    public static void illuminate(float[] material, float materialN, float[] l, float[] n, float[] v, float[] color, boolean shadow)
    {
		float r[] = new float[3]; // reflection vector
		float ln, rv; // scalar products <l,n> and <r,v>
		
		// <l,n>
		ln = l[0] * n[0] + l[1] * n[1] + l[2] * n[2];
		
		// reflection vector r=2*<l,n>*n-l
		r[0] = 2 * ln * n[0] - l[0];
		r[1] = 2 * ln * n[1] - l[1];
		r[2] = 2 * ln * n[2] - l[2];
		
		// <r,v>
		rv = r[0] * v[0] + r[1] * v[1] + r[2] * v[2];
		
		// ambient component, Ia*ra
		color[0] = Ia[0] * material[ambientIndex];
		color[1] = Ia[1] * material[ambientIndex+1];
		color[2] = Ia[2] * material[ambientIndex+2];
		
		// diffuse component, Ids*rd*<l,n>
		if (ln > 0 && !shadow) 
		//if (ln > 0)
		{
			color[0] += Ids[0] * material[difuseIndex] * ln;
			color[1] += Ids[1] * material[difuseIndex+1] * ln;
			color[2] += Ids[2] * material[difuseIndex+2] * ln;
			
			if (rv > 0)
			{
			    float pow = (float) Math.pow(rv, materialN);
			    color[0] += Ids[0] * material[specularIndex] * pow;
			    color[1] += Ids[1] * material[specularIndex+1] * pow;
			    color[2] += Ids[2] * material[specularIndex+2] * pow;
			}
		}
		
		// specular component, Ids*rs*<r,v>^n
		
		
		if (color[0] > 1)
			color[0] = 1.0f;
		if (color[1] > 1)
			color[1] = 1.0f;
		if (color[2] > 1)
			color[2] = 1.0f;
    }
}
